package com.example.model;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

/**
 * This class will hold the collection of the items created by the WheresMyStuff
 * users. It will create a static instance of the class to keep track for all of
 * the programs need, so there is very little need to transplant the ItemList
 * between activities and presenters.
 * 
 * @author 3Factorial
 */
public class ItemList {

	private static ItemList instance = null;
	private ArrayList<Item> items;

	/**
	 * Constructor for ItemList
	 */
	private ItemList() {
		items = new ArrayList<Item>();
	}

	/**
	 * Retrieves the current instance of the item list for use with the program.
	 * If an ItemList has not yet been created for this purpose, it will create
	 * one and send it along.
	 * 
	 * @return The ItemList currently in use by the program.
	 */
	public static ItemList getInstance() {
		if (instance == null) {
			instance = new ItemList();
		}
		return instance;
	}

	/**
	 * Adds an item to the ItemList.
	 * 
	 * @param i
	 *            The item to add to the collection.
	 */
	public void add(Item i) {
		items.add(i);
	}

	/**
	 * Returns the item at the given index.
	 * 
	 * @param index
	 *            The location of the item.
	 * @return The item at given location.
	 */
	public Item get(int index) {
		return items.get(index);
	}

	/**
	 * Creates an array list of the string description of each item in the
	 * collection.
	 * 
	 * @return The string array list of the descriptions of the items in the
	 *         collection.
	 */
	public List<String> toStringArray() {
		List<String> ans = new ArrayList<String>();
		for (int i = 0; i < items.size(); i++) {
			ans.add(items.get(i).toString());
		}
		return ans;
	}

	/**
	 * Determines if the given item name belongs to an item in the collection.
	 * If it does, it returns that item. If it does not, it returns null.
	 * 
	 * @param name
	 *            The item name to search for.
	 * @return The item if found; null if the item does not exist.
	 */
	public Item getItemByName(String name) {
		for (int i = 0; i < items.size(); i++) {
			if (items.get(i).getItemName().equals(name)) {
				return items.get(i);
			}
		}
		return null;
	}

	/**
	 * Creates a list containing all items with a given name.
	 * 
	 * @param name
	 * @return The list of all items with that name.
	 */

	public ArrayList<Item> getAllMatchedNames(String name) {
		ArrayList<Item> matches = new ArrayList<Item>();
		String l_name = name.toLowerCase(Locale.US);
		for (Item item : items) {
			if (item.getItemName().toLowerCase(Locale.US).matches(l_name)) {
				matches.add(item);
			}
		}
		return matches;
	}

	/**
	 * Creates an array list of items that match the given filter criteria.
	 * 
	 * @param filters
	 *            A list of filters to match with items.
	 * @return All the items that match the following filters.
	 */
	public ArrayList<Item> getMatchItems(ArrayList<String> filters) {

		if (filters.isEmpty()) {
			return items;
		}

		ArrayList<Item> matchItems = new ArrayList<Item>();
		for (Item i : items) {
			if (i.matchesAllFilters(filters)) {
				matchItems.add(i);
			}
		}

		return matchItems;
	}

	/**
	 * Returns an array list of all items.
	 * 
	 * @return All items.
	 */
	public ArrayList<Item> getAllItems() {
		return items;
	}

	/**
	 * @return A list of all lost items.
	 */
	public ArrayList<Item> getAllLostItems() {
		ArrayList<Item> toReturn = new ArrayList<Item>();
		for (Item i : items)
			if (i.isLost() == 0)
				toReturn.add(i);
		return toReturn;
	}

	/**
	 * @return A list of all found items.
	 */
	public ArrayList<Item> getAllFoundItems() {
		ArrayList<Item> toReturn = new ArrayList<Item>();
		for (Item i : items)
			if (i.isLost() == 1)
				toReturn.add(i);
		return toReturn;
	}

	/**
	 * Creates an empty list for testing purposes.
	 * 
	 * @return An empty ItemList
	 */
	public static ItemList getEmptyList() {
		ItemList list = new ItemList();
		list.clear();
		return list;
	}

	/**
	 * Clears the list of all items.
	 */
	private void clear() {
		items.clear();
	}

	/**
	 * Determines whether the given item is in the list.
	 * 
	 * @param item
	 *            Item to check for.
	 * @return True if item is in the list, false if not.
	 */
	public boolean contains(Item item) {
		return items.contains(item);
	}
} // End ItemList class